package com.hgkj.system.auth;

import cn.dev33.satoken.stp.StpUtil;
import com.hgkj.common.core.constant.SessionKeyConstant;
import com.hgkj.common.core.domain.model.LoginUser;
import com.hgkj.common.core.enums.UserStatus;
import com.hgkj.common.core.exception.ServiceException;
import com.hgkj.common.core.utils.ContextUtils;
import com.hgkj.common.core.utils.EncryptUtils;
import com.hgkj.common.async.AsyncManager;
import com.hgkj.system.async.factory.SystemAsyncTaskFactory;
import com.hgkj.system.domain.SysMenu;
import com.hgkj.system.domain.SysUser;
import com.hgkj.system.domain.dto.response.UserInfoResponse;
import com.hgkj.system.domain.vo.RouterVo;
import com.hgkj.system.service.SysMenuService;
import com.hgkj.system.service.SysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;

/**
 * 用户登陆 以及一些必要功能
 */
@Component
public class SysLoginService {

    private final SysUserService sysUserService;

    private final SysMenuService sysMenuService;

    public SysLoginService(SysUserService sysUserService,SysMenuService sysMenuService){
        this.sysUserService = sysUserService;
        this.sysMenuService = sysMenuService;
    }


    /**
     * 登陆放啊
     *
     * @param userName 用户名
     * @param password 密码
     * @return 用户ID
     * TODO 异步记录操作日志
     */
    public void login(String userName, String password) {
        // 登录前置检查
        loginPreCheck();
        SysUser sysUser = sysUserService.selectSysUserByUserName(userName);
        if (Objects.isNull(sysUser)) {
            throw new ServiceException("登陆用户名不存在");
        }
        if (!EncryptUtils.matchesPassword(password, sysUser.getPassword(), sysUser.getSalt())) {
            throw new ServiceException("密码错误");
        }
        if (sysUser.getStatus().equals(UserStatus.DISABLED.getCode())) {
            throw new ServiceException(UserStatus.DISABLED.getDesc());
        }
        StpUtil.login(sysUser.getUserId());
        LoginUser loginUser = new LoginUser();
        BeanUtils.copyProperties(sysUser, loginUser);
        StpUtil.getTokenSession().set(SessionKeyConstant.SUCCESS, loginUser);
        AsyncManager.getInstance().execute(SystemAsyncTaskFactory.afterUserLogin(sysUser.getUserId(), "登陆成功"));
    }

    /**
     * 登录前置检查
     * TODO IP黑名单
     */
    private void loginPreCheck() {

    }

    /**
     * 获取用户信息
     *
     * @return 响应信息
     */
    public UserInfoResponse getUserInfoByUserId() {
        SysUser sysUser = sysUserService.getUserInfoByUserId(ContextUtils.getUserId());
        if (Objects.isNull(sysUser)) {
            throw new ServiceException("用户不存在");
        }
        if (sysUser.getStatus().equals(UserStatus.DISABLED.getCode())) {
            throw new ServiceException("账号已冻结");
        }
        UserInfoResponse userInfo = new UserInfoResponse();
        BeanUtils.copyProperties(sysUser, userInfo);
        return userInfo;
    }

    /**
     * 获取本人所有路由信息
     *
     * @return routerVo
     */
    public List<RouterVo> getRouters() {
        List<SysMenu> menuList;
        if (ContextUtils.isAdmin()) {
            menuList = sysMenuService.getAllRouters();
        } else {
            menuList = sysMenuService.getRoutersByUserId(ContextUtils.getUserId());
        }
        return sysMenuService.buildMenus(menuList);
    }
}
